package com.cskaoyan.config.realm;

import com.cskaoyan.bean.po.*;
import com.cskaoyan.config.HashProperties;
import com.cskaoyan.mapper.MarketAdminMapper;
import com.cskaoyan.mapper.MarketAdminPermissionMapper;
import com.cskaoyan.mapper.MarketPermissionMapper;
import com.cskaoyan.mapper.MarketUserMapper;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;

/**
 * @Auther: Yang Yi-zhou
 * @Date: 2022/9/8 15:31
 * @Description: 注册Realm到容器中
 */

public class CustomRealm extends AuthorizingRealm {

    //    final static String SALT = "wd";
    @Autowired
    HashProperties hashProperties;

    @Autowired
    MarketAdminMapper marketAdminMapper;
    @Autowired
    MarketPermissionMapper marketPermissionMapper;
    @Autowired
    MarketAdminPermissionMapper marketAdminPermissionMapper;
    @Autowired
    MarketUserMapper marketUserMapper;

    /**
     * 根据token去做一个登陆的验证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 拿到username
        String username = (String) authenticationToken.getPrincipal();
        CustomToken customToken = (CustomToken) authenticationToken;
        String type = customToken.getType();
        if ("admin".equals(type)) {
            // 根据username去数据库查询
            MarketAdminExample example = new MarketAdminExample();
            example.createCriteria().andUsernameEqualTo(username);
            List<MarketAdmin> marketAdmins = marketAdminMapper.selectByExample(example);
            if (marketAdmins.size() > 0) {
                // 这里只需要把principal和credentials封装到AuthenticationInfo返回回去，Shiro会自己去完成剩下的认证操作
                return new SimpleAuthenticationInfo(marketAdmins.get(0), marketAdmins.get(0).getPassword(), ByteSource.Util.bytes(hashProperties.getSalt()), getName());
            }
        } else if ("wx".equals(type)) {
            MarketUserExample example = new MarketUserExample();
            example.createCriteria().andUsernameEqualTo(username);
            List<MarketUser> marketUsers = marketUserMapper.selectByExample(example);
            if (marketUsers.size() > 0) {
                return new SimpleAuthenticationInfo(marketUsers.get(0), marketUsers.get(0).getPassword(), ByteSource.Util.bytes(hashProperties.getSalt()), getName());
            }
        }

        return null;
    }

    // 拿到Principal去数据库查询该用户所拥有的Permission，然后封装到simpleAuthorizationInfo返回
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        Object primaryPrincipal = principalCollection.getPrimaryPrincipal();
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        if (primaryPrincipal instanceof MarketAdmin) {
            MarketAdmin admin = (MarketAdmin) primaryPrincipal;
            Integer[] roleIds = admin.getRoleIds();
            HashSet<String> permSet = new HashSet<>();
            for (Integer roleId : roleIds) {
                MarketPermissionExample example = new MarketPermissionExample();
                example.createCriteria().andRoleIdEqualTo(roleId);
                List<MarketPermission> marketPermissions = marketPermissionMapper.selectByExample(example);
                for (MarketPermission marketPermission : marketPermissions) {
                    String permission = marketPermission.getPermission();
                    if ("*".equals(permission)) {
                        permSet.clear();
                        permSet.add("*");
                        break;
                    }
                    permSet.add(permission);
                }
            }

            for (String perm : permSet) {
                // 超级管理员
                if ("*".equals(perm) && permSet.size() == 1) {
                    MarketAdminPermissionExample example = new MarketAdminPermissionExample();
                    List<MarketAdminPermission> marketAdminPermissions = marketAdminPermissionMapper.selectByExample(example);
                    for (MarketAdminPermission marketAdminPermission : marketAdminPermissions) {
                        simpleAuthorizationInfo.addStringPermission(marketAdminPermission.getApi());
                    }
                    break;
                }
                MarketAdminPermissionExample example = new MarketAdminPermissionExample();
                example.createCriteria().andApiIdEqualTo(perm);
                List<MarketAdminPermission> marketAdminPermissions = marketAdminPermissionMapper.selectByExample(example);
                for (MarketAdminPermission marketAdminPermission : marketAdminPermissions) {
                    simpleAuthorizationInfo.addStringPermission(marketAdminPermission.getApi());
                }
            }
        }
        return simpleAuthorizationInfo;
    }

}
